package com.atlin.project.controller;

import cn.hutool.json.JSONUtil;
import com.atlin.project.annotation.AuthCheck;
import com.atlin.project.common.BaseResponse;
import com.atlin.project.common.DeleteRequest;
import com.atlin.project.common.ErrorCode;
import com.atlin.project.common.ResultUtils;
import com.atlin.project.contant.UserConstant;
import com.atlin.project.exception.BusinessException;
import com.atlin.project.exception.ThrowUtils;
import com.atlin.project.model.domain.Notification;
import com.atlin.project.model.domain.User;
import com.atlin.project.model.dto.notification.NotificationAddRequest;
import com.atlin.project.model.dto.notification.NotificationQueryRequest;
import com.atlin.project.model.dto.notification.NotificationUpdateRequest;
import com.atlin.project.model.vo.NotificationSdkVO;
import com.atlin.project.model.vo.NotificationVO;
import com.atlin.project.service.NotificationService;
import com.atlin.project.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 模版接口
 *
 * @author atlin
 */
@RestController
@RequestMapping("/notification")
@Slf4j
public class NotificationController {

    @Resource
    private NotificationService notificationService;

    @Resource
    private UserService userService;

    private final static Gson GSON = new Gson();
    

    // region 增删改查

    /**
     * 创建
     *
     * @param notificationAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addNotification(@RequestBody NotificationAddRequest notificationAddRequest, HttpServletRequest request) {
        if (notificationAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Notification notification = new Notification();
        BeanUtils.copyProperties(notificationAddRequest, notification);
        List<String> domainList = notificationAddRequest.getDomain();

        notificationService.validNotification(notification, domainList, true);
        User loginUser = userService.getLoginUser(request);
        notification.setUserId(loginUser.getId());

        if (domainList != null) {
            notification.setDomain(JSONUtil.toJsonStr(domainList));
        }

        boolean result = notificationService.save(notification);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        long newNotificationId = notification.getId();
        return ResultUtils.success(newNotificationId);
    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteNotification(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        Notification oldNotification = notificationService.getById(id);
        ThrowUtils.throwIf(oldNotification == null, ErrorCode.NULL_ERROR);

        boolean b = notificationService.removeById(id);
        return ResultUtils.success(b);
    }

    /**
     * 更新（仅管理员）
     *
     * @param notificationUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateNotification(@RequestBody NotificationUpdateRequest notificationUpdateRequest) {
        if (notificationUpdateRequest == null || notificationUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Notification notification = new Notification();
        BeanUtils.copyProperties(notificationUpdateRequest, notification);
        List<String> domainList = notificationUpdateRequest.getDomain();

        // 参数校验
        notificationService.validNotification(notification, domainList, false);
        long id = notificationUpdateRequest.getId();
        // 判断是否存在
        Notification oldNotification = notificationService.getById(id);
        ThrowUtils.throwIf(oldNotification == null, ErrorCode.NULL_ERROR);
        
        if (domainList != null) {
            notification.setDomain(JSONUtil.toJsonStr(domainList));
        }
        boolean result = notificationService.updateById(notification);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Notification> getNotificationById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Notification notification = notificationService.getById(id);
        if (notification == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        return ResultUtils.success(notification);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<NotificationVO> getNotificationVOById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Notification notification = notificationService.getById(id);
        if (notification == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }

        NotificationVO notificationVO = new NotificationVO();
        BeanUtils.copyProperties(notification, notificationVO);
        return ResultUtils.success(notificationVO);
    }

    /**
     * 分页获取列表（封装类）
     *
     * @param notificationQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<NotificationVO>> listNotificationVOByPage(@RequestBody NotificationQueryRequest notificationQueryRequest,
                                                                       HttpServletRequest request) {
        long current = notificationQueryRequest.getCurrent();
        long size = notificationQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<Notification> notificationPage = notificationService.page(new Page<>(current, size),
                new QueryWrapper<>());

        List<Notification> notificationList = notificationPage.getRecords();

        Page<NotificationVO> notificationVOPage = new Page<>(notificationPage.getCurrent(), notificationPage.getSize(), notificationPage.getTotal());
        if (CollectionUtils.isEmpty(notificationList)) {
            return ResultUtils.success(notificationVOPage);
        }

        ArrayList<NotificationVO> notificationVOList = new ArrayList<>();
        for (Notification notification : notificationList) {
            NotificationVO notificationVO = NotificationVO.objToVo(notification);
            notificationVOList.add(notificationVO);
        }

        notificationVOPage.setRecords(notificationVOList);

        return ResultUtils.success(notificationVOPage);
    }

    /**
     * 分页获取题目列表（仅管理员）
     *
     * @param notificationQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Notification>> listNotificationByPage(@RequestBody NotificationQueryRequest notificationQueryRequest,
                                                                   HttpServletRequest request) {
        long current = notificationQueryRequest.getCurrent();
        long size = notificationQueryRequest.getPageSize();
        Page<Notification> notificationPage = notificationService.page(new Page<>(current, size),
                notificationService.getQueryWrapper(notificationQueryRequest));
        return ResultUtils.success(notificationPage);
    }
    
    
    @GetMapping("/getNotificationSdkVO")
    public BaseResponse<NotificationSdkVO> getNotificationSdkVO(@RequestParam String domain) {
        if (domain.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"域名为空");
        }
        QueryWrapper<Notification> wrapper = new QueryWrapper<>();
        wrapper.like("domain", "\"" + domain + "\"");
        Notification notification = notificationService.getOne(wrapper);
        if (notification == null) {
            return ResultUtils.success(null);
        }
        
        Integer status = notification.getStatus();
        // 没有开启通知
        if (status == 0) {
            return ResultUtils.success(null);
        }

        Date startTime = notification.getStartTime();
        Date endTime = notification.getEndTime();
        if (startTime == null || endTime == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"开始时间后结束时间为空");
        }
        // 当前时间
        Date date = new Date();
        // 当前通知不在时间范围内
        if (date.before(startTime) || date.after(endTime)) {
            return ResultUtils.success(null);
        }
        log.info("getNotificationSdkVO:{}",notification);
        NotificationSdkVO notificationSdkVO = notificationService.getNotificationSdkVO(notification);
        return ResultUtils.success(notificationSdkVO);
    }

    // endregion

}
